package com.zx.notification.producer.listener;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zx.notification.common.dao.NotificationChannelsConfigMapper;
import com.zx.notification.common.dao.SystemNotificationsMapper;
import com.zx.notification.common.event.NotificationPushEvent;
import com.zx.notification.common.model.NotificationChannelsConfig;
import com.zx.notification.common.model.SystemNotifications;
import com.zx.notification.producer.mq.MqPushService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 通知推送事件监听器
 * 监听通知推送事件，根据MQ类型执行相应的推送处理
 * 支持从数据库读取MQ配置信息
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class NotificationPushEventListener {

    private final MqPushService mqPushService;
    private final SystemNotificationsMapper systemNotificationsMapper;
    private final NotificationChannelsConfigMapper notificationChannelsConfigMapper;
    private final ObjectMapper objectMapper;

    /**
     * 处理通知推送事件
     * 根据MQ类型执行相应的推送处理
     *
     * @param event 通知推送事件
     */
    @EventListener
    @Async("mqTaskExecutor")
    public void handleNotificationPushEvent(NotificationPushEvent event) {
        try {
            log.info("开始处理通知[{}]的{}消息推送任务", event.getNotificationId(), event.getMqType());

            // 获取通知信息和渠道配置
            SystemNotifications notification = getNotification(event);
            if (notification == null) return;

            NotificationChannelsConfig channelConfig = getChannelConfig(event);
            if (channelConfig == null) return;

            // 构建消息内容
            Map<String, Object> messageData = buildMessageData(event, notification);

            String message = objectMapper.writeValueAsString(messageData);

            // 根据MQ类型执行相应的推送处理
            mqPushService.pushMessage(event.toPushTask(), message);

            log.info("通知[{}]的{}消息推送任务处理完成", event.getNotificationId(), event.getMqType());
        } catch (Exception e) {
            log.error("处理通知[{}]的{}消息推送任务时发生错误", event.getNotificationId(), event.getMqType(), e);
        }
    }

    /**
     * 获取通知信息
     *
     * @param event 通知推送事件
     * @return 通知信息
     */
    private SystemNotifications getNotification(NotificationPushEvent event) {
        SystemNotifications notification = systemNotificationsMapper.selectByPrimaryKey(event.getNotificationId());
        if (notification == null) {
            log.warn("未找到通知ID为[{}]的通知信息", event.getNotificationId());
        }
        return notification;
    }

    /**
     * 获取渠道配置
     *
     * @param event 通知推送事件
     * @return 渠道配置
     */
    private NotificationChannelsConfig getChannelConfig(NotificationPushEvent event) {
        NotificationChannelsConfig channelConfig = notificationChannelsConfigMapper.selectByChannelType(event.getChannelType());
        if (channelConfig == null) {
            log.warn("未找到渠道类型为[{}]的配置信息", event.getChannelType());
        }
        return channelConfig;
    }

    /**
     * 构建消息内容
     *
     * @param event        通知推送事件
     * @param notification 通知信息
     * @return 消息内容
     */
    private Map<String, Object> buildMessageData(NotificationPushEvent event, SystemNotifications notification) {
        Map<String, Object> messageData = new java.util.HashMap<>();
        messageData.put("notificationId", event.getNotificationId());
        messageData.put("mqType", event.getMqType());
        messageData.put("consumeMode", event.getConsumeMode());
        messageData.put("destinationName", event.getDestinationName());
        messageData.put("destinationType", event.getDestinationType());
        messageData.put("channelType", event.getChannelType());
        // 添加任务ID
        messageData.put("taskId", event.getTaskId());

        if (event.getRoutingKey() != null) {
            messageData.put("routingKey", event.getRoutingKey());
        }

        if (event.getTag() != null) {
            messageData.put("tag", event.getTag());
        }

        // 添加通知内容
        messageData.put("title", notification.getTitle());
        messageData.put("content", notification.getContent());
        messageData.put("userId", notification.getUserId());
        messageData.put("bizType", notification.getBizType());
        messageData.put("bizId", notification.getBizId());
        messageData.put("bizUrl", notification.getBizUrl());
        messageData.put("expireTime", notification.getExpireTime());
        messageData.put("createTime", notification.getCreateTime());

        return messageData;
    }
}